package net.entelijan.config.impl2;

import java.util.Date;
import java.util.List;

import javax.swing.AbstractButton;
import javax.swing.text.JTextComponent;
import javax.xml.datatype.XMLGregorianCalendar;

import net.entelijan.cobean.core.ICobean;
import net.entelijan.cobean.text.DefaultTextInitializer;
import net.entelijan.cobean.text.ITextConverter;
import net.entelijan.cobean.text.converter.DateTextConverter;
import net.entelijan.cobean.text.converter.IntTextConverter;
import net.entelijan.cobean.text.converter.LongTextConverter;
import net.entelijan.cobean.text.converter.StringTextConverter;
import net.entelijan.cobean.text.converter.XMLGregorianCalendarTextConverter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.ClassUtils;

public class DefaultTextInitializerBinderFactory extends AbstractBinderFactory {

	@SuppressWarnings("unused")
	private static Log log = LogFactory
			.getLog(DefaultTextInitializerBinderFactory.class);

	public DefaultTextInitializerBinderFactory() {
		super();
	}

	protected boolean isCoreComponent(IEnhancedComponent comp) {
		return (comp.getComponent() instanceof JTextComponent)
				&& !isMatchingComponent(comp, JTextComponent.class, "failure");
	}

	protected List<List<String>> adjustPathesOfCoreComponent(
			List<List<String>> pathes) {
		return PathUtil.removeSuffixesIgnoreCase(pathes, "TextField",
				"TextArea");
	}

	@SuppressWarnings("unchecked")
	protected ICobean<?> createCobean(final IEnhancedComponent coreComp,
			final List<IEnhancedComponent> allComps, Class<?> modelType,
			Object config) {
		JTextComponent core = (JTextComponent) coreComp.getComponent();
		JTextComponent failureComponent = findComponent(allComps, coreComp,
				JTextComponent.class, "failure");
		AbstractButton resetButton = findComponent(allComps, coreComp,
				AbstractButton.class, "reset");
		DefaultTextInitializer<?> ini = new DefaultTextInitializer();
		ini.setCoTextComponent(core);
		ini.setCoFailureComponent(failureComponent);
		ini.setCoResetButton(resetButton);
		ITextConverter conv = createConverter(modelType);
		if (conv != null) {
			ini.setConverter(conv);
		}
		return ini.initialize();
	}

	@SuppressWarnings("unchecked")
	private <T> ITextConverter<T> createConverter(Class<?> modelType) {
		ITextConverter re = null;
		if (ClassUtils.isAssignable(Date.class, modelType)) {
			re = new DateTextConverter("yyyy-MM-dd");
		} else if (ClassUtils.isAssignable(Integer.class, modelType)) {
			re = new IntTextConverter();
		} else if (ClassUtils.isAssignable(int.class, modelType)) {
			re = new IntTextConverter();
		} else if (ClassUtils.isAssignable(Long.class, modelType)) {
			re = new LongTextConverter();
		} else if (ClassUtils.isAssignable(long.class, modelType)) {
			re = new LongTextConverter();
		} else if (ClassUtils.isAssignable(String.class, modelType)) {
			re = new StringTextConverter();
		} else if (ClassUtils.isAssignable(XMLGregorianCalendar.class,
				modelType)) {
			re = new XMLGregorianCalendarTextConverter("yyyy-MM-dd");
		}
		return re;
	}

}
